package com.estar.integaration.strategy;

import com.estar.integaration.Parser.NaturalSentenceParse;
import com.estar.integaration.Util.DateParseUtil;
import com.estar.integaration.Util.Util;
import com.estar.integaration.entity.paymentPlanEntity.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Author: YJL
 * Date: 2022/2/17 23:15
 **/
public class PaymentPlanContext {

  List<PurchaseOrderDetail> purchaseOrderDetailList = null;
  List<DueReceiptDetail> dueReceiptDetailList = null;
  List<ReceiptComeLedger> receiptComeLedgerList = null;
  List<SupplierAccountPeriod> supplierAccountPeriodList = null;
  List<SupplierAccountMultipleSituation> supplierAccountMultipleSituationList = null;
  Map<String,Map<String,List<SupplierAccountMultipleSituation>>> multipleSituationMap = new HashMap<>();

  //单据编号及应付单一项(<单据编号,到期日>)
  Map<String,DueReceiptDetail> dueReceiptDetailMap = null;
  //<供应商,付款条件>
  Map<String,SupplierAccountPeriod> supplierAccountPeriodMap = null;
  //<单据编号，发票到票台账>
  Map<String,ReceiptComeLedger> receiptComeLedgerMap = null;


  public PaymentPlanContext(List<PurchaseOrderDetail> purchaseOrderDetailList, List<DueReceiptDetail> dueReceiptDetailList, List<ReceiptComeLedger> receiptComeLedgerList, List<SupplierAccountPeriod> supplierAccountPeriodList,List<SupplierAccountMultipleSituation> supplierAccountMultipleSituationList) {
    this.purchaseOrderDetailList = purchaseOrderDetailList;
    this.dueReceiptDetailList = dueReceiptDetailList;
    this.receiptComeLedgerList = receiptComeLedgerList;
    this.supplierAccountPeriodList = supplierAccountPeriodList;
    this.supplierAccountMultipleSituationList = supplierAccountMultipleSituationList;

  }

  public List<PurchaseOrderDetail> execute(){
    // <"合同号",{a,b,c,d...}>和合同号下的子物料
    Map<String,List<PurchaseOrderDetail>> orderNumberGroup = null;
    //首先对purchaseOrderDetailList进行分组，一个合同号一个组
    if(purchaseOrderDetailList != null){
      orderNumberGroup = purchaseOrderDetailList.stream().collect(Collectors.groupingBy(PurchaseOrderDetail::getOrderNumber));
    }
    multipleSituationMap = getMutipleSituationHashMap(supplierAccountMultipleSituationList);
    //单据编号及应付单一项(<单据编号,到期日>)
    dueReceiptDetailMap = getdueReceiptDetailMapfromdueReceiptList(dueReceiptDetailList);
    //<供应商,付款条件>
    supplierAccountPeriodMap = getSupplierAccountPeriodMapfromList(supplierAccountPeriodList);
    //<单据编号，发票到票台账>
    receiptComeLedgerMap = getReceiptComLedgerMapfromList(receiptComeLedgerList);
    //去除YNN
    System.out.println("删除之前的所有数量"+purchaseOrderDetailList.size());
    orderNumberGroup = getPTnePA(orderNumberGroup);
    List<PurchaseOrderDetail> returnList = new ArrayList<>();
    /**
     * 计算数量代码
     */
    int leftSize = 0;
    for (Map.Entry<String,List<PurchaseOrderDetail>> en : orderNumberGroup.entrySet()){
        leftSize += en.getValue().size();
    }
    System.out.println("删除物料之后剩下的值"+leftSize);
    /**
     * 需要保证完备性:
     * 每个物料均需要处理和记录，不能直接丢掉
     */
    int allBeforeSize = 0;
    int allAfterSize = 0;
    for(Map.Entry<String,List<PurchaseOrderDetail>> en : orderNumberGroup.entrySet()){
        //N未付全款
        List<PurchaseOrderDetail> purchaseOrderDetailList = en.getValue();
        //已处理 SIT-P20201130-15 SIT-P20210511-03
      //test用
        if(en.getKey().equals("SIT-P20210113-05"))//这个是有应付单号
          System.out.println("test");
//        Boolean solveRes = solveResult(purchaseOrderDetailList.get(0),purchaseOrderDetailList,dueReceiptDetailMap,supplierAccountPeriodMap,receiptComeLedgerMap,en.getKey());
        Boolean solveRes = false;
      /**
       * 为什么要for，有的物料的一行里面，有的字段默默奇妙消失，比如某一个关键字段，应付金额什么的一个空了但是别的不空
       */
      int debug_before_solver_size = purchaseOrderDetailList.size();
      int debug_after_solver_size = 0;
      allBeforeSize += debug_before_solver_size;
//      System.out.println(en.getKey());
//      System.out.println("处理前podList长度"+debug_before_solver_size);
      for(int i = 0 ; i < purchaseOrderDetailList.size() ;i++){
        solveRes = solveResult(purchaseOrderDetailList.get(i),purchaseOrderDetailList,dueReceiptDetailMap,supplierAccountPeriodMap,receiptComeLedgerMap,en.getKey(),orderNumberGroup,multipleSituationMap);
        purchaseOrderDetailList = orderNumberGroup.get(en.getKey());
        if(solveRes == true)
//          debug_after_solver_size = purchaseOrderDetailList.size();
//          System.out.println("处理后podList长度" + debug_after_solver_size);
          break;
        }
        debug_after_solver_size = purchaseOrderDetailList.size();//经过solveRes true或者没经过的长度
        allAfterSize += debug_after_solver_size;
//        System.out.println("出循环后podList长度" + debug_after_solver_size);
        if(debug_before_solver_size != debug_after_solver_size){
            System.out.println("===================");
            System.out.println(en.getKey());
            System.out.println("处理前podList长度"+debug_before_solver_size);
            System.out.println("处理后podList长度" + debug_after_solver_size);
            System.out.println("===================");
        }
        /**
        if(purchaseOrderDetailList == null || purchaseOrderDetailList.size() == 0)
          continue;
        if(purchaseOrderDetailList.get(0).getInventoryVoucherNumber() != null){//Y 已入库
          if(purchaseOrderDetailList.get(0).getDueNumber() != null){//Y
            //NYY
            StrategyNYY strategyNYY = new StrategyNYY(purchaseOrderDetailList.get(0).getDueNumber(),dueReceiptDetailMap);
            strategyNYY.setExpectDate(purchaseOrderDetailList);
          }else if(purchaseOrderDetailList.get(0).getDueNumber() == null){//N
            //NYN
            StrategyNYN strategyNYN = new StrategyNYN(supplierAccountPeriodMap);
            strategyNYN.setExpectDate(purchaseOrderDetailList);
          }
        }else {//N未入库
            if(purchaseOrderDetailList.get(0).getDueNumber() == null && receiptComeLedgerMap.get(en.getKey()) != null){
              //NNY
              StrategyNNY strategyNNY = new StrategyNNY(receiptComeLedgerMap,supplierAccountPeriodMap);
              strategyNNY.setExpectDate(purchaseOrderDetailList);
            }else if(purchaseOrderDetailList.get(0).getDueNumber() == null && receiptComeLedgerMap.get(en.getKey()) == null){
              //NNN
              StrategyNNN strategyNNN = new StrategyNNN();
              strategyNNN.setExpectDate(purchaseOrderDetailList);
            }
        }**/
        returnList.addAll(purchaseOrderDetailList);
    }
    System.out.println("处理前长度" + allBeforeSize);
    System.out.println("处理后长度" + allAfterSize);
    setTaxPoint(returnList,receiptComeLedgerMap,dueReceiptDetailMap);
    return returnList;
  }

  /**
   * 第二层解析
   * @param purchaseOrderDetailList 错误物料，需要兜底
   * @return
   */
  public List<PurchaseOrderDetail> twiceLayerAnalyse(List<PurchaseOrderDetail> purchaseOrderDetailList){
    //对List进行分类
    List<PurchaseOrderDetail> returnList = new LinkedList<>();
    Map<String,Map<String,Map<String,List<PurchaseOrderDetail>>>> PODMap = purchaseOrderDetailList.stream().collect(
      Collectors.groupingBy(PurchaseOrderDetail::getSupplierName,
          Collectors.groupingBy(PurchaseOrderDetail::getMaterialNumber,
              Collectors.groupingBy(PurchaseOrderDetail::getDueNumber)
              ))
    );
    //一层,遍历所有供应商名
    for(Map.Entry<String, Map<String, Map<String, List<PurchaseOrderDetail>>>> s : PODMap.entrySet()){
        Map<String, Map<String, List<PurchaseOrderDetail>>> materialCodeMap = s.getValue();
        //二层，遍历所有的物料号
        for(Map.Entry<String,Map<String,List<PurchaseOrderDetail>>> e : materialCodeMap.entrySet()){
          Map<String, List<PurchaseOrderDetail>> APMap = e.getValue();
          //三层，所有的AP号List
          for(Map.Entry<String,List<PurchaseOrderDetail>> m : APMap.entrySet()){
            List<PurchaseOrderDetail> thisPodList = m.getValue();//拿到当前AP号下的所有purchaseOrderDetail
            //进行三层赋值
            for(PurchaseOrderDetail pod : thisPodList){//一个一个来
              returnList.addAll(threeLayerSetValue(pod,m.getKey()));
            }
          }
        }
    }
    return returnList;
  }


  /**
   * 三层赋值,对错误物料进行处理
   * @param purchaseOrderDetail
   * @return
   */
  private List<PurchaseOrderDetail> threeLayerSetValue(PurchaseOrderDetail purchaseOrderDetail,String dueNumber){
    purchaseOrderDetail.setType("XXX");//额外情况
    List<PurchaseOrderDetail> tLayerPodList = new ArrayList<>();
    //处理第一层
    if(dueReceiptDetailMap != null){//是否有AP
      if(dueReceiptDetailMap.containsKey(dueNumber)){
        DueReceiptDetail dueReceiptDetail = dueReceiptDetailMap.get(dueNumber);
        if(dueReceiptDetail != null && purchaseOrderDetail.getAmountDue() != null
            && (Math.abs(purchaseOrderDetail.getAmountDue() ) > 0.000001) //(有应付金额,即应付金额>0.00001)
        ){
          purchaseOrderDetail.setExpectPayDate(dueReceiptDetail.getExpireDate());
          purchaseOrderDetail.setNeedPayAmount(purchaseOrderDetail.getAmountDue());//设置成应付金额
          tLayerPodList.add(purchaseOrderDetail);
        }
      }
    }
    //第二层  入库日期
    if(purchaseOrderDetail.getInventoryDate() == null
        || purchaseOrderDetail.getInventoryDate().equals("")
        || purchaseOrderDetail.getInventoryDate().equals(" ")
    ){}  //没有无法进入第二层
    else{//第二层
      purchaseOrderDetail.setExpectPayDate(purchaseOrderDetail.getInventoryDate());
      purchaseOrderDetail.setNeedPayAmount(purchaseOrderDetail.getInventoryMoney());//设置成应付金额
      if(multipleSituationMap.containsKey(purchaseOrderDetail.getSupplierName())){//有这种自然语言
        List<PurchaseOrderDetail> tmpPodList = new ArrayList<>();
        tmpPodList.add(purchaseOrderDetail);//包装成ArrayList在进行处理，因为方法接一个List,返回一个新的List，可能一个变成多个，因为是MultipleSitu
        List<PurchaseOrderDetail> newPodListByMultiPleSituation = splitDateAndMoneySolveByMultipleSitu(tmpPodList,purchaseOrderDetail,multipleSituationMap.get(purchaseOrderDetail.getSupplierName()));
        tLayerPodList.addAll(newPodListByMultiPleSituation);
      }
    }
    //第三层 交货日期和倒票日期不是空
    if(purchaseOrderDetail.getTicketComeTime() != null ){
      purchaseOrderDetail.setExpectPayDate(purchaseOrderDetail.getTicketComeTime());
      purchaseOrderDetail.setNeedPayAmount(purchaseOrderDetail.getPriceTaxGather());
      if(multipleSituationMap.containsKey(purchaseOrderDetail.getSupplierName())){//有这种自然语言
        List<PurchaseOrderDetail> tmpPodList = new ArrayList<>();
        tmpPodList.add(purchaseOrderDetail);//包装成ArrayList在进行处理，因为方法接一个List,返回一个新的List，可能一个变成多个，因为是MultipleSitu
        List<PurchaseOrderDetail> newPodListByMultiPleSituation = splitDateAndMoneySolveByMultipleSitu(tmpPodList,purchaseOrderDetail,multipleSituationMap.get(purchaseOrderDetail.getSupplierName()));
        tLayerPodList.addAll(newPodListByMultiPleSituation);
      }
    }else if(purchaseOrderDetail.getDeliveryGoodsDate() !=null){ //这里彻底兜底
      purchaseOrderDetail.setExpectPayDate(purchaseOrderDetail.getDeliveryGoodsDate());
      purchaseOrderDetail.setNeedPayAmount(purchaseOrderDetail.getPriceTaxGather());
      if(multipleSituationMap.containsKey(purchaseOrderDetail.getSupplierName())){//有这种自然语言
        List<PurchaseOrderDetail> tmpPodList = new ArrayList<>();
        tmpPodList.add(purchaseOrderDetail);//包装成ArrayList在进行处理，因为方法接一个List,返回一个新的List，可能一个变成多个，因为是MultipleSitu
        List<PurchaseOrderDetail> newPodListByMultiPleSituation = splitDateAndMoneySolveByMultipleSitu(tmpPodList,purchaseOrderDetail,multipleSituationMap.get(purchaseOrderDetail.getSupplierName()));
        tLayerPodList.addAll(newPodListByMultiPleSituation);
      }
    }else {//到第三层还是什么都没有
      purchaseOrderDetail.setExpectPayDate("无兜底");
    }
    return tLayerPodList;
  }




  /**
   * list转成Hash{供应商名称,{是否有入库单号,{List}}}
   * @param supplierAccountMultipleSituationList
   * @return
   */
  private Map<String,Map<String,List<SupplierAccountMultipleSituation>>> getMutipleSituationHashMap(List<SupplierAccountMultipleSituation> supplierAccountMultipleSituationList){
    Map<String,Map<String,List<SupplierAccountMultipleSituation>>> multipleSituationMap = new HashMap<>();
    multipleSituationMap = supplierAccountMultipleSituationList.stream()
        .collect(Collectors.groupingBy(SupplierAccountMultipleSituation::getSupplierName,Collectors.groupingBy(SupplierAccountMultipleSituation::getIfHaveInventoryNumber)));
    return multipleSituationMap;
  }


  /**
   * 兜底解析
   * @return
   */
  private Boolean childSolve(
      PurchaseOrderDetail p , List<PurchaseOrderDetail> purchaseOrderDetailList,
      Map<String,DueReceiptDetail> dueReceiptDetailMap,
      Map<String,SupplierAccountPeriod> supplierAccountPeriodMap,
      Map<String,ReceiptComeLedger> receiptComeLedgerMap,
      String orderNumber, //n.getKey
      Map<String,List<PurchaseOrderDetail>> orderNumberGroup, //传进来HashMap，把需要改的List改掉
      Map<String,Map<String,List<SupplierAccountMultipleSituation>>> multipleSituationMap //多情况
  ){


    return false;
  }

  /**
   * 解决出现物料无时间或者时间为空的情况，即第一个物料并不能推算出结果
   * true出结果 false未出结果
   */
  private Boolean solveResult(PurchaseOrderDetail p , List<PurchaseOrderDetail> purchaseOrderDetailList,
                              Map<String,DueReceiptDetail> dueReceiptDetailMap,
                              Map<String,SupplierAccountPeriod> supplierAccountPeriodMap,
                              Map<String,ReceiptComeLedger> receiptComeLedgerMap,
                              String orderNumber, //n.getKey
                              Map<String,List<PurchaseOrderDetail>> orderNumberGroup, //传进来HashMap，把需要改的List改掉
                              Map<String,Map<String,List<SupplierAccountMultipleSituation>>> multipleSituationMap //多情况
  ){
    if(purchaseOrderDetailList == null || purchaseOrderDetailList.size() == 0)
      return false;
    if(p.getInventoryVoucherNumber() != null){
      if(p.getDueNumber() != null){
        //NYY
        StrategyNYY strategyNYY = new StrategyNYY(p.getDueNumber(),dueReceiptDetailMap);
        String naturalSentence = ifCanInSplit(p,supplierAccountPeriodMap);
        if(naturalSentence != null || multipleSituationMap.containsKey(p.getSupplierName())){
          if(p.getAmountDue() != null){
            DueReceiptDetail dueReceiptDetail = dueReceiptDetailMap.get(p.getDueNumber());
            if(dueReceiptDetail == null){
              purchaseOrderDetailList.forEach(pod->pod.setExpectPayDate("找不到应付单时间"));
            }
            setPreposedTmpExpectDateandTmpMoney(purchaseOrderDetailList,dueReceiptDetail.getExpireDate(),p.getAmountDue(),"NYY");
          }
          //设置type和special
          purchaseOrderDetailList.forEach(pod ->
              {
                pod.setType("NYY");
                pod.setIfSpecial(true);
              }
          );
          List<PurchaseOrderDetail> splitPODList = null;
          //自然语言空则是在web设置了multipleSitu
          if(naturalSentence == null || naturalSentence.equals("")){
            strategyNYY.setExpectDate(purchaseOrderDetailList,p,"NYY");//对PODList进行预处理
            splitPODList = splitDateAndMoneySolveByMultipleSitu(purchaseOrderDetailList,p,multipleSituationMap.get(p.getSupplierName()));
          }else {
            splitPODList = splitDateandMoneySolve(purchaseOrderDetailList,p,naturalSentence);
          }
          orderNumberGroup.put(orderNumber,splitPODList);
          return true;
        }
        return strategyNYY.setExpectDate(purchaseOrderDetailList,p,"NYY");
      }else if(p.getDueNumber() == null){//N
        //NYN
        StrategyNYN strategyNYN = new StrategyNYN(supplierAccountPeriodMap);
        //供应商账期需要多个解析的情况下，进入拆开分支
        String naturalSentence = ifCanInSplit(p,supplierAccountPeriodMap);
        /**x
         * 按照规则设置一个暂时的ExpectDate,因为拆开需要一个ExpectDate
         */
        if(naturalSentence != null || multipleSituationMap.containsKey(p.getSupplierName())){//有自然语言
          /**初始化**/
          if(p.getInventoryMoney() != null ) {
            setPreposedTmpExpectDateandTmpMoney(purchaseOrderDetailList,p.getInventoryDate(),p.getInventoryMoney(),"NYN");
          }
          purchaseOrderDetailList.forEach(
              pod->
              {
                pod.setType("NYN");
                pod.setIfSpecial(true);
              }
          );

          //进入拆开分支
          List<PurchaseOrderDetail> splitedPODList = null;
          if(naturalSentence == null || naturalSentence.equals("")){//自然语言不空那么一定是有multiple
            strategyNYN.setExpectDate(purchaseOrderDetailList,p,"NYN");
            splitedPODList = splitDateAndMoneySolveByMultipleSitu(purchaseOrderDetailList,p,multipleSituationMap.get(p.getSupplierName()));
          }else {
            splitedPODList = splitDateandMoneySolve(purchaseOrderDetailList,p,naturalSentence);
          }
          //代替原List
          orderNumberGroup.put(orderNumber,splitedPODList);
          return true;
        }else {//无自然语言
          return strategyNYN.setExpectDate(purchaseOrderDetailList,p,"NYN");
        }
      }
    }else {//N未入库
      if(p.getDueNumber() == null && receiptComeLedgerMap.get(orderNumber) != null){
        /**初始化**/
        //NNY
        StrategyNNY strategyNNY = new StrategyNNY(receiptComeLedgerMap,supplierAccountPeriodMap);
        //供应商账期需要多个解析的情况下，进入拆开分支
        String naturalSentence = ifCanInSplit(p,supplierAccountPeriodMap);
        //NNY是发票到票台账
        ReceiptComeLedger receiptComeLedger = receiptComeLedgerMap.get(p.getOrderNumber());
        if(receiptComeLedger == null){
          p.setExpectPayDate("发票无到票台账");   //失败的时候设置一个就行，成功的时候设置全部。
          return false;//如果没有发票到票台账直接算失败了
        }
        /****/
        if(naturalSentence != null || multipleSituationMap.containsKey(p.getSupplierName())){
          if(p.getPriceTaxGather() != null){
            //设置默认的ExpectDate
            setPreposedTmpExpectDateandTmpMoney(purchaseOrderDetailList,receiptComeLedger.getTicketComeTime(),p.getPriceTaxGather(),"NNY");
          }
          purchaseOrderDetailList.forEach(pod->
              {
                pod.setType("NNY");
                pod.setIfSpecial(true);
              }
          );
          //进入拆开分支
          List<PurchaseOrderDetail> splitedPODList = null;
          if(naturalSentence == null  || naturalSentence.equals("") ){//自然语言不空那么一定是有multiple
            strategyNNY.setExpectDate(purchaseOrderDetailList, p,"NNY");
            splitedPODList = splitDateAndMoneySolveByMultipleSitu(purchaseOrderDetailList,p,multipleSituationMap.get(p.getSupplierName()));
          }else {
            splitedPODList = splitDateandMoneySolve(purchaseOrderDetailList,p,naturalSentence);
          }
          //代替原List
          orderNumberGroup.put(orderNumber,splitedPODList);
          return true;
        }else {//无自然语言
          return strategyNNY.setExpectDate(purchaseOrderDetailList, p,"NNY");
        }
      }else if(p.getDueNumber() == null && receiptComeLedgerMap.get(orderNumber) == null){
        //NNN
        StrategyNNN strategyNNN = new StrategyNNN(supplierAccountPeriodMap);
        //供应商账期需要多个解析的情况下，是否进入拆开分支
        String naturalSentence = ifCanInSplit(p,supplierAccountPeriodMap);
        //NNN是采购订单执行明细的交货日期
        if(naturalSentence != null || multipleSituationMap.containsKey(p.getSupplierName())){//有自然语言
          if(p.getPriceTaxGather() != null  || naturalSentence.equals("") ){
            setPreposedTmpExpectDateandTmpMoney(purchaseOrderDetailList,p.getDeliveryGoodsDate(),p.getPriceTaxGather(),"NNN");
          }
          purchaseOrderDetailList.forEach(pod->
              {
                pod.setType("NNN");
                pod.setIfSpecial(true);
              }
          );
          //进入拆开分支
          List<PurchaseOrderDetail> splitedPODList = null;
          if(naturalSentence == null || multipleSituationMap.containsKey(p.getSupplierName())){//自然语言不空那么一定是有multiple
            strategyNNN.setExpectDate(purchaseOrderDetailList, p,"");
            splitedPODList = splitDateAndMoneySolveByMultipleSitu(purchaseOrderDetailList,p,multipleSituationMap.get(p.getSupplierName()));
          }else {
            splitedPODList = splitDateandMoneySolve(purchaseOrderDetailList,p,naturalSentence);
          }
//          //进入拆开分支
//          purchaseOrderDetailList =  splitDateandMoneySolve(purchaseOrderDetailList,p,naturalSentence);
          //代替原List
          orderNumberGroup.put(orderNumber,splitedPODList);
          return true;
        }else {//无自然语言
          return strategyNNN.setExpectDate(purchaseOrderDetailList, p,"");
        }
      }else if(p.getDueNumber() != null || p.getDueNumber().equals("") || p.getDueNumber().equals(" ")){
         purchaseOrderDetailList.forEach(
             po -> {
               po.setExpectPayDate("ERR");
               po.setIfSpecial(false);
             }
         );
         return true;
      }
    }
    //如果上面没有任何一个解析了，则肯定失败
    return false;
  }


  /**
   * Split出来的List如果想处理，那么默认日期(入库日期/到票日期/交货日期)先加0设置ExpectDate，进入Split中，加入天数。由于需要一个默认的ExcpectDate,加0的，
   * 和默认的钱
   * @param purchaseOrderDetailList
   * @param date 日期未加供应商账期的默认日期
   * 设置前置默认日期
   */
  private void setPreposedTmpExpectDateandTmpMoney(List<PurchaseOrderDetail> purchaseOrderDetailList,String date,Double money,String code){
    for(PurchaseOrderDetail p : purchaseOrderDetailList){
      p.setExpectPayDate(date);
      if(code.equals("NYN")){
        p.setNeedPayAmount(p.getInventoryMoney());//日期肯定相同，但是每个的钱是不一样的，所以设置成自己的钱
      }else if(code.equals("NYY")){
          p.setNeedPayAmount(p.getAmountDue());
      } else
      {
        p.setNeedPayAmount(p.getPriceTaxGather());
      }
    }
//    purchaseOrderDetailList.forEach(
//        p-> {
//          p.setExpectPayDate(date);
//          p.setNeedPayAmount(money);
//        }
//    );
  }

  /**
   * 是否需要拆开进入Split
   * @return
   */
  private String ifCanInSplit(PurchaseOrderDetail purchaseOrderDetail,Map<String,SupplierAccountPeriod> supplierAccountPeriodMap){
    if(supplierAccountPeriodMap == null)
      return null;
    if(purchaseOrderDetail == null)
      return null;
    String supplierName = purchaseOrderDetail.getSupplierName();
    if(supplierName == null)
      return null;
    SupplierAccountPeriod supplierAccountPeriod = supplierAccountPeriodMap.get(supplierName);
    if(supplierAccountPeriod == null){
      return null;
    }
    if(supplierAccountPeriod.getNaturalSentence() != null )
      return supplierAccountPeriod.getNaturalSentence();
    else
      return null;
  }

  /**
   * 拆开钱和日期,并且返回一个新的拆开后的List,用此List代替原List
   * @return
   */
  private List<PurchaseOrderDetail> splitDateandMoneySolve(List<PurchaseOrderDetail> purchaseOrderDetailList,PurchaseOrderDetail p,String sentence){
    List<PurchaseOrderDetail> newPurchaseOrderDetailList = new ArrayList<>();
    NaturalSentenceParse naturalSentenceParse = new NaturalSentenceParse();
    newPurchaseOrderDetailList = naturalSentenceParse.operateThisPODfromNaturalSentence(purchaseOrderDetailList,p,sentence);
    return newPurchaseOrderDetailList;
  }

  private List<PurchaseOrderDetail> splitDateAndMoneySolveByMultipleSitu(List<PurchaseOrderDetail> purchaseOrderDetailList,PurchaseOrderDetail p,Map<String,List<SupplierAccountMultipleSituation>> multiSituHashMap){
    List<PurchaseOrderDetail> newPurchaseOrderDetailList = new ArrayList<>();
    newPurchaseOrderDetailList = operateThisPODfromMultipleSituation(purchaseOrderDetailList, p, multiSituHashMap);
    return newPurchaseOrderDetailList;
  }


  /**
   * 通过有入库号的Hash和没入库号的hash内的List进行计算
   * @param purchaseOrderDetailList
   * @param purchaseOrderDetail
   * @param multipleSituationMap
   * @return
   */
  private List<PurchaseOrderDetail> operateThisPODfromMultipleSituation(List<PurchaseOrderDetail> purchaseOrderDetailList,PurchaseOrderDetail purchaseOrderDetail,Map<String,List<SupplierAccountMultipleSituation>> multipleSituationMap){
    List<PurchaseOrderDetail> newPurchaseOrderDetailList = new ArrayList<>();
    List<SupplierAccountMultipleSituation> supplierAccountMultipleSituationhaveNumberList = multipleSituationMap.get("have");
    List<SupplierAccountMultipleSituation> supplierAccountMultipleSituationNoNumberList = multipleSituationMap.get("no");
    List<SupplierAccountMultipleSituation> percentageList = multipleSituationMap.get("percentage");//只有一个,同一个SupplierName只有一个

    if(supplierAccountMultipleSituationhaveNumberList != null && supplierAccountMultipleSituationNoNumberList!=null){
      //若无入库单号
      if(purchaseOrderDetail.getInventoryVoucherNumber() == null
          || purchaseOrderDetail.getInventoryVoucherNumber().equals("")
          || purchaseOrderDetail.getInventoryVoucherNumber().equals(" ")
          || purchaseOrderDetail.getInventoryVoucherNumber().equals("null")
      ){
        for (SupplierAccountMultipleSituation supplierAccountMultipleSituation : supplierAccountMultipleSituationNoNumberList){
          Integer addDay = Integer.parseInt(supplierAccountMultipleSituation.getNeedAddDay());
          Double moneyPercentage = supplierAccountMultipleSituation.getPercentage();
          List<PurchaseOrderDetail> tmpPurchaseOrderDetailList = setAllDateandMoneyinMaterialFromList(purchaseOrderDetailList,addDay,moneyPercentage);
          newPurchaseOrderDetailList.addAll(tmpPurchaseOrderDetailList);
        }
      }else {//若有入库单号
        for (SupplierAccountMultipleSituation supplierAccountMultipleSituation : supplierAccountMultipleSituationhaveNumberList){
          Integer addDay = Integer.parseInt(supplierAccountMultipleSituation.getNeedAddDay());
          Double moneyPercentage = supplierAccountMultipleSituation.getPercentage();
          List<PurchaseOrderDetail> tmpPurchaseOrderDetailList = setAllDateandMoneyinMaterialFromList(purchaseOrderDetailList,addDay,moneyPercentage);
          newPurchaseOrderDetailList.addAll(tmpPurchaseOrderDetailList);
        }
      }
    }else {//有percentage则按照percentage解析
      if(percentageList != null &&  percentageList.size() > 0){
        SupplierAccountMultipleSituation supplierAccountMultipleSituation = percentageList.get(0);
        for(PurchaseOrderDetail pod : purchaseOrderDetailList){
          pod.setNeedPayAmount(pod.getNeedPayAmount()*supplierAccountMultipleSituation.getPercentage()*0.01);
          newPurchaseOrderDetailList.add(pod);
        }
      }else {
        //没有任何变化
        newPurchaseOrderDetailList = purchaseOrderDetailList;
      }
    }
    return newPurchaseOrderDetailList;
  }

  /**
   * 每个物料都要拆成这样的n个
   * 如果是两个交期，则每个物料进行拆分成二
   * @param purchaseOrderDetailList
   * @return
   */
  private List<PurchaseOrderDetail> setAllDateandMoneyinMaterialFromList(List<PurchaseOrderDetail> purchaseOrderDetailList,Integer addDay,Double moneyPercentage){
    List<PurchaseOrderDetail> newPurchaseOrderDetailList = new ArrayList<>();
    //整个list进行，本次拆开的更新循环，例如这是第0天，百分之30,所有物料均加0乘百分之三十
    for(PurchaseOrderDetail p : purchaseOrderDetailList){
      //原pod->新pod
      PurchaseOrderDetail tmpPurchaseOrderDetail = clonePurchaseOrderDetail(p);
      //ExpectPayDate是解析出结果之后的加上拆开日期的最终日期
      tmpPurchaseOrderDetail.setExpectPayDate(DateParseUtil.dateAddAccountPeriod(tmpPurchaseOrderDetail.getExpectPayDate(),String.valueOf(addDay)));
      //原本的钱拆散
      tmpPurchaseOrderDetail.setNeedPayAmount(tmpPurchaseOrderDetail.getNeedPayAmount()*moneyPercentage*0.01);
      newPurchaseOrderDetailList.add(tmpPurchaseOrderDetail);
    }
    return newPurchaseOrderDetailList;
  }



  /**
   * 克隆老物料到新物料
   * @param purchaseOrderDetail
   * @return
   */
  public PurchaseOrderDetail clonePurchaseOrderDetail(PurchaseOrderDetail purchaseOrderDetail){
    PurchaseOrderDetail newPurchaseOrderDetail = new PurchaseOrderDetail(Util.getUUID(),
        purchaseOrderDetail.getOrderNumber(),
        purchaseOrderDetail.getPurchaseGroup(),
        purchaseOrderDetail.getSupplierName(),
        purchaseOrderDetail.getMaterialNumber(),
        purchaseOrderDetail.getMaterialName(),
        purchaseOrderDetail.getSpec(),
        purchaseOrderDetail.getDeliveryGoodsDate(),
        purchaseOrderDetail.getPredeterminedNumber(),
        purchaseOrderDetail.getPriceWithTax(),
        purchaseOrderDetail.getPriceTaxGather(),
        purchaseOrderDetail.getInventoryDate(),
        purchaseOrderDetail.getInventoryVoucherNumber(),
        purchaseOrderDetail.getInventoryMoney(),
        purchaseOrderDetail.getDueNumber(),
        purchaseOrderDetail.getAmountDue(),
        purchaseOrderDetail.getPayAmount(),
        purchaseOrderDetail.getDrawingNo(),
        purchaseOrderDetail.getBrand(),
        purchaseOrderDetail.getExpectPayDate(),
        purchaseOrderDetail.getNeedPayAmount(),
        purchaseOrderDetail.getType(),
        purchaseOrderDetail.getIfSpecial(),
        purchaseOrderDetail.getTicketComeTime(),
        purchaseOrderDetail.getTaxPoint(),
        purchaseOrderDetail.getNeedPayDate()
    );
    return newPurchaseOrderDetail;
  }



  /**
   * 从应付单List到应付单HashMap
   * @param dueReceiptDetailList
   * @return
   */
  private Map<String,DueReceiptDetail> getdueReceiptDetailMapfromdueReceiptList(List<DueReceiptDetail> dueReceiptDetailList){
    Map<String,DueReceiptDetail> dueReceiptDetailMap = new HashMap<>();
    dueReceiptDetailList.forEach(dueReceiptDetail -> dueReceiptDetailMap.put(dueReceiptDetail.getOrderNumber(),dueReceiptDetail));
    return dueReceiptDetailMap;
  }

  /**
   * 从发票到票到账-><单据编号,到票日期>
   * @param receiptComeLedgerList
   * @return
   */
  private Map<String,ReceiptComeLedger> getReceiptComLedgerMapfromList(List<ReceiptComeLedger> receiptComeLedgerList){
    Map<String,ReceiptComeLedger> receiptComeLedgerMap = new HashMap<>();
    receiptComeLedgerList.forEach(r -> receiptComeLedgerMap.put(r.getOrderNumber(),r));
    return receiptComeLedgerMap;
  }

  /**
   * 从发票到票到账-><单据编号,到票日期>
   * @param supplierAccountPeriods
   * @return
   */
  private Map<String,SupplierAccountPeriod> getSupplierAccountPeriodMapfromList (List<SupplierAccountPeriod> supplierAccountPeriods){
    Map<String,SupplierAccountPeriod> receiptComeLedgerMap = new HashMap<>();
    supplierAccountPeriods.forEach(r -> receiptComeLedgerMap.put(r.getSupplierName(),r));
    return receiptComeLedgerMap;
  }


  /**
   * 计算价税合计之和和付款金额之和的关系,留出价税合计之和不相等的
   */
  private Map<String,List<PurchaseOrderDetail>> getPTnePA(Map<String,List<PurchaseOrderDetail>> orderNumberGroup){
    List<String> waitRemoveKey = new ArrayList<>();
    int size = 0;
    for(Map.Entry<String,List<PurchaseOrderDetail>> en : orderNumberGroup.entrySet()){
        if(en.getKey().equals("SIT-P20201014-01"))
          System.out.println("找到了");
        //如果如果相等排除//Y已付全款
        if(en.getValue() == null){
          System.out.println(en.getKey());
          continue;
        }

        if(ifMoneyEq(en.getValue())){
          //YNN去掉
          waitRemoveKey.add(en.getKey());
          size += en.getValue().size();
        }
    }
    for(String k : waitRemoveKey){
      orderNumberGroup.remove(k);
    }
    System.out.println("去掉的无付款计划的物料数量为:" + size);
    return orderNumberGroup;
  }

  /**
   * 判断一个List内的所有价税之和是否等于一个List内所有的付款金额之和
   */
  private Boolean ifMoneyEq(List<PurchaseOrderDetail> purchaseOrderDetailList){
    Double allPriceTaxSum = 0.0;
    Double allPaymentMoneySum = 0.0;
    Double dis = 1e-6;
    for(PurchaseOrderDetail p : purchaseOrderDetailList){
      if(p.getPriceTaxGather() == null){
        return false;
      }
      allPriceTaxSum += p.getPriceTaxGather();
      if(p.getPayAmount() == null) //如果是空则绝对没有付完
        return false;
      allPaymentMoneySum += p.getPayAmount();
    }
    if(Math.abs(allPriceTaxSum - allPaymentMoneySum) < dis){
      return true;
    }else {
      return false;
    }
  }

  //ctrl+B进实现 ctl+Q看注释 ctrl+Y删除整行  ctrl+D复制整行 ctrl+w 选中这部分

  /**
   * 设置税点
   * @param purchaseOrderDetailList
   */
  private List<PurchaseOrderDetail> setTaxPoint(List<PurchaseOrderDetail> purchaseOrderDetailList,Map<String,ReceiptComeLedger> receiptComeLedgerMap,Map<String,DueReceiptDetail> dueReceiptDetailMap){
    for (PurchaseOrderDetail p : purchaseOrderDetailList){
      String orderNumber = p.getOrderNumber();//单据编号
      ReceiptComeLedger receiptComeLedger = null;
      if(receiptComeLedgerMap.containsKey(orderNumber)){
        receiptComeLedger = receiptComeLedgerMap.get(orderNumber);
        //设置税点
        if(receiptComeLedger.getTaxPoint() != null //税点不为空 满足了
        ){
          if(!receiptComeLedger.getTaxPoint().equals(" ")//不是空
          && !receiptComeLedger.getTaxPoint().equals("")
          ){
            p.setTaxPoint(receiptComeLedger.getTaxPoint());
          }
        }
        //设置到票日期
        if(receiptComeLedger.getTicketComeTime() != null){//倒票日期不空
          if(!receiptComeLedger.getTicketComeTime().equals(" ")
              && !receiptComeLedger.getTicketComeTime().equals("")){
              p.setTicketComeTime(receiptComeLedger.getTicketComeTime());
          }
        }
      }
      //设置到期日
      if(dueReceiptDetailMap.containsKey(p.getDueNumber())){
        DueReceiptDetail dueReceiptDetail = dueReceiptDetailMap.get(p.getDueNumber());
        if(dueReceiptDetail.getExpireDate() != null){
          if (!dueReceiptDetail.getExpireDate().equals(" ")
              && !dueReceiptDetail.getExpireDate().equals("")
          ) {
            p.setNeedPayDate(dueReceiptDetail.getExpireDate());
          }
        }
      }
    }
    return purchaseOrderDetailList;
  }












}
